//
//  STPlayerViewController.swift
//  iPhone
//
//  Created by Toj on 1/9/23.
//

import UIKit

private let defaultPlayerHeight = CGFloat.dv_width.zoom16_9
class STPlayerViewController: STBaseViewController {
    
    private let viewModel = STPlayerViewModel()
    
    private lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        // cell之间 垂直间距
        layout.minimumLineSpacing = 8
        // cell之间 水平间距
        layout.minimumInteritemSpacing = 0
        layout.itemSize = CGSize(width: .dv_width, height: 66)
        
        let view = UICollectionView(frame: .zero, collectionViewLayout: layout)
        view.showsVerticalScrollIndicator = false
        view.showsHorizontalScrollIndicator = false
        view.backgroundColor = .white
        view.register(cellClass: STCollectionViewCell.self)
        view.dataSource = self
        view.delegate = self
        return view
    }()
    
    private(set) lazy var playerRootView: UIImageView = {
        let view = UIImageView()
        view.contentMode = .scaleAspectFit
        view.backgroundColor = .random
        return view
    }()
    
    private(set) lazy var gestureView: UIView = {
        let view = UIView()
        let tap = UITapGestureRecognizer(target: self, action: #selector(didTapGesture))
        view.addGestureRecognizer(tap)
        return view
    }()
    
    private(set) lazy var marqueeView: STMarqueeView = {
        let view = STMarqueeView()
        view.marqueeLabel.text = "012234445678"
        view.marqueeImageView.image = "player_marquee_icon".to_image
        return view
    }()
    
    private var isScrolling = false
    private var isShowedMaxHeight = true
    private var rootViewMinHeight: CGFloat = defaultPlayerHeight
    private var rootViewHeight   : CGFloat = defaultPlayerHeight
    private var max_minHeight: CGFloat = 0
    private var rootViewMaxHeight: CGFloat = defaultPlayerHeight { didSet {
        isShowedMaxHeight = false
        showMaxRootView()
    } }
    private var currentOffset = CGPoint.zero
    
    /* 展示半屏内容视图 */
    private lazy var fullDetailContentView: UIView = {
        let view = UIView()
        view.isHidden = true
        return view
    }()
    
    /* <#NOTE#> */
    private lazy var productViewController: HProductController = {
        let vc = HProductController()
        vc.view.isHidden = true
        vc.pdelegate = self
        return vc
    }()
    
    /* showProductView */
    private lazy var showProductView: UIButton = {
        let view = UIButton()
        view.frame = CGRect(origin: .zero, size: CGSize(width: 100, height: 35))
        view.setTitle("商品", for: .normal)
        view.addTarget(self, action: #selector(didTapShowProduct), for: .touchUpInside)
        return view
    }()
    
    /* showAdView */
    private lazy var showAdView: UIButton = {
        let view = UIButton()
        view.frame = CGRect(origin: .zero, size: CGSize(width: 100, height: 35))
        view.setTitle("广告", for: .normal)
        view.addTarget(self, action: #selector(didTapShowAd), for: .touchUpInside)
        return view
    }()
}

// MARK: - 生命周期
extension STPlayerViewController {
    
    open override var shouldAutorotate: Bool {
        return true
    }
    
    // 支持哪些屏幕方向
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .allButUpsideDown
    }
    
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .portrait
    }
    
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        
        coordinator.animate { context in
            if size.width > size.height {
                self.resetupPlayerRootView(size: size)
                return
            }
            self.resetupPlayerRootView()
        }
    }
    
    override var pagePath: String {
        return "startimes://player"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupMakeInitialize()
        setupMakeAddSubviews()
        setupMakeLayoutSubviews()
    }
    
    func presentAppOpenAd() {
        print("-->toj: 读取本地缓存数据 func:" + #function)
        guard let admobModel = STAdManager.manager.appOpenAdmobModelCache() else {
            STAdmobManager.manager.requestAppOpenAd()
            print("-->toj: 本地没有缓存数据 func1:" + #function)
            return
        }
        
        let isPreparedAd = STAdmobManager.manager.isPreparedAd(admobModel: admobModel)
        guard isPreparedAd else {
            print("-->toj: app没有预加载的广告对象 func:" + #function)
            STAdmobManager.manager.requestAppOpenAd()
            return
        }
        
        print("-->toj: 有预加载的广告对象 func:" + #function)
        STAdmobManager.manager.presentAd(admobModel: admobModel)
        DispatchQueue.main.asyncAfter(deadline: .now()+0.05) { [weak self] in
            STAdmobManager.manager.requestAppOpenAd()
        }
    }
}

// MARK: - 点击事件
@objc private extension STPlayerViewController {
    
    func didTapGesture() {
        presentAppOpenAd()
        //navigationBar.isHidden = !navigationBar.isHidden
    }
    
    func didTapShowProduct() {
        let isSelectedTV = arc4random_uniform(2) == 1
        print("-->toj: isSelectedTV: \(isSelectedTV)")
        showProduct(admobModel: nil, isSelectedTV: isSelectedTV)
    }
    
    func didTapShowAd() {
        showProduct(admobModel: STAdmobModel())
    }
    
    func showProduct(admobModel: STAdmobModel?, isSelectedTV: Bool = false) {
        fullDetailContentView.bringSubviewToFront(productViewController.view)
        fullDetailContentView.isHidden = false
        collectionView.setContentOffset(collectionView.contentOffset, animated: false)
        
        rootViewHeight = rootViewMinHeight
        resetupPlayerRootView()
        
        productViewController.showAnimate(admobModel: admobModel, selectedTV: isSelectedTV)
        
        testBarHeight()
    }
}

// MARK: - Private
private extension STPlayerViewController {
    
    func showMaxRootView() {
        guard !isScrolling else { return }
        isShowedMaxHeight = true
        
        guard fullDetailContentView.isHidden else { return }
        
        rootViewHeight = rootViewMaxHeight
        max_minHeight = rootViewMaxHeight - rootViewMinHeight
        resetupPlayerRootView()
    }
}

// MARK: - 代理事件 productControllerDidTapClosed
extension STPlayerViewController: HProductControllerDelegate {
    
    func productControllerDidTapClosed(_ vc: HProductController) {
        fullDetailContentView.isHidden = vc.view.isHidden
    }
}

// MARK: - 代理事件
extension STPlayerViewController: UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 100
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifierClass: STCollectionViewCell.self, for: indexPath)
        let pointer = Unmanaged<AnyObject>.passUnretained(cell as AnyObject).toOpaque()
        cell.numberString = "address: \(pointer), num:" + String(indexPath.row)
        
        cell.contentView.backgroundColor = .random
        return cell
    }
}

extension STPlayerViewController: UICollectionViewDelegate {
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let cell = collectionView.cellForItem(at: indexPath, convertTo: STCollectionViewCell.self) else { return }
        print("-->toj: cell name: \(cell.numberString)")
    }
    
    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        guard let _ = cell as? STCollectionViewCell else { return }
        
    }
    
    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        guard let _ = cell as? STCollectionViewCell else { return }
        
    }
}

extension STPlayerViewController {
    
    func scrollContentOffset(contentOffset: CGPoint) {
        
        if currentOffset.st_isyZero {
            // print("-->toj: offsetY:\(0), setY: \(0)")
            currentOffset = contentOffset
            return
        }
        
        let offsetY = contentOffset.y
        let setY = currentOffset.y - offsetY
//        let setYs    = String(format: "%.2f" , setY)
//        let offsetYs = String(format: "%.2f" , offsetY)
        // print("-->toj: offsetY:\(offsetYs), setY: \(setYs)")
        
        currentOffset = contentOffset
        if setY > 0 && offsetY > max_minHeight {
            //  print("-->toj: offsetY2:\(0), setY1: \(0)")
            return
        }
        // offsetY: 上托 +, setY: 上托 > 0, 负值
        // offsetY: 下托 -, setY: 下托 < 0, 正值
        
        var _rheight = rootViewHeight + setY
        //print("-->toj: rootViewHeight:\(rootViewHeight), rheight:\(_rheight)")
        if offsetY <= 0 {
            if rootViewHeight == rootViewMaxHeight {
                //print("-->toj: h1:\(rootViewHeight), rmH:\(rootViewMaxHeight)")
                return
            }
            
            if rootViewHeight > rootViewMaxHeight {
                _rheight = rootViewMaxHeight
            }
            else {
                _rheight = rootViewHeight + abs(setY)
            }
        }
        
        if _rheight < rootViewMinHeight {
            if rootViewHeight == rootViewMinHeight {
                // print("-->toj: h2:\(rootViewHeight), rminH:\(rootViewMinHeight)")
                return
            }
            _rheight = rootViewMinHeight
        }
        if _rheight > rootViewMaxHeight {
            if rootViewHeight == rootViewMaxHeight {
                //   print("-->toj: h3:\(rootViewHeight), rminH:\(rootViewMaxHeight)")
                return
            }
            _rheight = rootViewMaxHeight
        }
        rootViewHeight = _rheight
        resetupPlayerRootView()
    }
}

extension STPlayerViewController: UIScrollViewDelegate {
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        print("-->toj: func:\(#function)")
        isScrolling = true
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let contentOffset = scrollView.contentOffset
        scrollContentOffset(contentOffset: contentOffset)
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        print("-->toj: func:\(#function)")
        isScrolling = false
        guard !isShowedMaxHeight else { return }
        showMaxRootView()
    }
    
    func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
        return productViewController.view.isHidden
    }
}

// MARK: - 初始化设置
private extension STPlayerViewController {
    
    func setupMakeAddSubviews() {
        
        view.addSubview(collectionView)
        view.addSubview(fullDetailContentView)
        view.addSubview(playerRootView)
        view.addSubview(gestureView)
        
        addChild(productViewController)
        fullDetailContentView.addSubview(productViewController.view)
        
        playerRootView.addSubview(marqueeView)
    }
    
    func resetupPlayerRootView(size: CGSize = .zero) {
        
        var arect = CGRect(origin: .zero, size: size)
        if size.st_isZero {
            guard UIApplication.shared.app_orientation.isPortrait else {
                return
            }
            arect.size = CGSize(width: .sr_width, height: rootViewHeight)
            // arect = CGRect(origin: CGPoint(x: 0, y: .nav_barFullHeight), size: )
        }
        playerRootView.frame = arect
    }
    
    func setupMakeLayoutSubviews() {
        
        resetupPlayerRootView()
        
        collectionView.snp.makeConstraints { make in
            make.top.equalTo(playerRootView.snp.bottom)
            make.left.right.bottom.equalTo(view)
        }
        
        marqueeView.snp.makeConstraints { make in
            make.bottom.left.right.equalTo(view)
            make.height.equalTo(1)
        }
        
        fullDetailContentView.snp.remakeConstraints { make in
            make.left.right.bottom.equalTo(view)
            make.top.equalTo(playerRootView.snp.bottom)
        }
        
        productViewController.view.snp.remakeConstraints { make in
            make.edges.equalTo(fullDetailContentView)
        }
        
        gestureView.snp.makeConstraints { make in
            make.edges.equalTo(playerRootView)
        }
    }
    
    func setupMakeInitialize() {
        view.backgroundColor = .white
        
        tt_isNavigationBarHidden = true
        navigationBar.leftBarView?.isHidden = true
        navigationBar.backgroundColor = navigationBar.backgroundColor?.tt_alpha(0.75)
        navigationBar.rightBarViews = [showAdView, showProductView]
        navigationBar.isHidden = true
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
            self?.marqueeView.startMarquee()
        }
        let maxHeight = CGFloat.dv_height - rootViewMinHeight
        print("-->toj: def rHeight: \(rootViewMinHeight)")
        let rHeight = CGFloat(arc4random_uniform(UInt32(maxHeight))) + rootViewMinHeight
        
        let imageURL = "https://i-7.vcimg.com/trim/5048802142b7bb86b444e3600720ea5a940142/trim.jpg"
        
        guard let source = URL(string: imageURL) else { return }
        playerRootView.kf.setImage(with: source, placeholder: "com_placeholder_164x92".to_image) { [weak self] result in
            var mHeight = defaultPlayerHeight
            switch result {
            case .success(let value):
                print("-->toj: rHeight: \(rHeight)")
                let _width = value.image.size.width
                let _height = value.image.size.height
                mHeight = CGFloat.dv_width * _height / _width
            case.failure(_):
                break
            }
            
            DispatchQueue.main.asyncAfter(deadline: .now()+2) {
                self?.rootViewMaxHeight = mHeight
                self?.resetupPlayerRootView()
            }
        }
    }
}

private extension STPlayerViewController {
    
    func testBarHeight() {
        let application = UIApplication.shared
        
        print("-->UTests: \n")
        print("-->UTests: other:")
        print("-->UTests: app: safeAreaInsets: \(application.app_safeAreaInsets)")
        
        print("-->UTests: statusBar:")
        print("-->UTests: statusBar: app_height: \(application.statusBarFrame.height)")
        print("-->UTests: statusBar: sts_height: \(CGFloat.sts_barHeight)")
        
        print("-->UTests: navBar:")
        
        print("-->UTests: navBar: heightd: \(CGFloat.nav_barHeight)")
        print("-->UTests: navBar: height2: \(CGFloat.nav_barHeight2)")
        print("-->UTests: navBar: nav_safeHeight: \(CGFloat.nav_barFullHeight)")
        
        print("-->UTests: navBar: leftMargin    : \(CGFloat.dv_safeAreaLeft)")
        
        print("-->UTests: tabBar:")
        print("-->UTests: tabBar: safeAreaHeight: \(CGFloat.tab_safeAreaHeight)")
        print("-->UTests: tabBar: fullHeight : \(CGFloat.tab_barFullHeight)")
        print("-->UTests: \n")
    }
}
